#include "cgal_source_halfedge.h"
#include "cgal_defines.hpp"
#include <CGAL/Aff_transformation_3.h>
#include <CGAL/Kernel/global_functions_3.h>
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <CGAL/aff_transformation_tags.h>
#include <algorithm>
#include <cmath>
#include <initializer_list>
#include <iterator>
#include <vector>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkProp3D.h>
#include <vtkRenderer.h>
#include <vtkTransform.h>
#include <vtkType.h>

#include "gen_halfedge.h"

namespace cgalView {
vtkTypeBool
cgal_source_halfedge::RequestData(vtkInformation *request,
                                  vtkInformationVector **inInfoVector,
                                  vtkInformationVector *outInfoVector) {
  if (!d_mesh) {
    return false;
  }

  if (!d_mesh->number_of_halfedges()) {
    return false;
  }

  auto output = vtkPolyData::GetData(outInfoVector);

  auto points = vtkPoints::New();

  auto lines = vtkCellArray::New();
  for (auto e : d_mesh->halfedges()) {
    if (d_mesh->is_border(e)) {
      continue;
    }
    std::vector<vtkIdType> line{};
    std::vector<vtkIdType> arrow{};

    vector_type normal{};
    normal = CGAL::Polygon_mesh_processing::compute_face_normal(d_mesh->face(e),
                                                                *d_mesh);
    auto start = d_mesh->point(d_mesh->source(e));
    auto end = d_mesh->point(d_mesh->target(e));
    auto poly = d_gen.gen(start, end, normal);
    auto si = points->GetNumberOfPoints();

    points->InsertNextPoint(poly[0].x(), poly[0].y(), poly[0].z());
    for (size_t i = 1; i < poly.size(); ++i) {
      auto const &pnt = poly.at(i);
      points->InsertNextPoint(pnt.x(), pnt.y(), pnt.z());
      std::vector<vtkIdType> line{};
      lines->InsertNextCell({vtkIdType(i - 1 + si), vtkIdType(i + si)});
    }
  }

  output->SetPoints(points);
  output->SetLines(lines);
  return true;
}
} // namespace cgalView